#include "Chessman.h"
#include "Util.h"
#include "Mesh.h"
#include "Node.h"
#include "Player.h"
#include "Game.h"
#include "Math.h"

#include <iostream>
using namespace std;

static Color gColorDark = Color(0.1f, 0.1f, 0.1f, 1.0f);
static Color gColorLight = Color(0.8902f, 0.1490f, 0.2118f, 1.0f);
static Color gColorHighlight = Color(0.0000f, 0.8078f, 0.8196f, 1.0f);

Chessman::Chessman( int x, int y, int owner )
{
	mPosX = x;
	mPosY = y;
	mOwner = owner;
	mIsKing = false;

	BuildMesh();
}

Chessman::~Chessman(void)
{
}

void Chessman::BuildMesh()
{
	const int division = 48;
	Vector3 vertices[48];
	Vector3 center;

	BuildCircleVertices(center, 0.4f, division, vertices);

	VertexBuffer* vb = new VertexBuffer();
	IndexBuffer* ib = new IndexBuffer();

	Vertex cv;
	cv.position = center;
	
	int index = 0;

	for (int i = 0; i < division; i++)
	{
		Vertex v1;
		Vertex v2;
		Vertex v3;
		Vertex v4;
		
		v1.position = vertices[i];
		v2.position = vertices[(i+1) % division];
		v3.position = v1.position;
		v4.position = v2.position;

		v3.position.z -= 0.3f;
		v4.position.z -= 0.3f;

		vb->push_back(cv);
		ib->push_back(index++);
		vb->push_back(v1);
		ib->push_back(index++);
		vb->push_back(v2);
		ib->push_back(index++);

		vb->push_back(cv);
		ib->push_back(index++);
		vb->push_back(v2);
		ib->push_back(index++);
		vb->push_back(v1);
		ib->push_back(index++);

		vb->push_back(v1);
		ib->push_back(index++);
		vb->push_back(v3);
		ib->push_back(index++);
		vb->push_back(v4);
		ib->push_back(index++);

		vb->push_back(v1);
		ib->push_back(index++);
		vb->push_back(v4);
		ib->push_back(index++);
		vb->push_back(v2);
		ib->push_back(index++);
	}

	Mesh* mesh = new Mesh();
	mesh->SetVertexBuffer(vb);
	mesh->SetIndexBuffer(ib);
	
	if (mOwner == PLAYER_ONE)
	{
		mesh->SetColor(gColorDark);
	}
	else 
	{
		mesh->SetColor(gColorLight);
	}

	mNode->SetMesh(mesh);

	UpdateTransformation();
}

void Chessman::UpdateTransformation()
{
	mNode->SetPosition(Vector3((float)mPosX - 0.5f, (float)mPosY - 0.5f, 0.8f));
}

void Chessman::OnSelect()
{
	Game::GetGame()->SelectChessman(this);
}

void Chessman::SetSelected( bool selected )
{
	Mesh *mesh = mNode->GetMesh();

	if (!selected)
	{
		if (mOwner == PLAYER_ONE) 
		{
			mesh->SetColor(gColorDark);
		}
		else 
		{
			mesh->SetColor(gColorLight);
		}
	}
	else 
	{
		mesh->SetColor(gColorHighlight);
	}
}

void Chessman::SetPosition( int x, int y )
{
	mPosX = x;
	mPosY = y;

	if (mOwner == PLAYER_ONE && mPosY == 8)
	{
		mIsKing = true;
	}

	if (mOwner == PLAYER_TWO && mPosY == 1)
	{
		mIsKing = true;
	}

	UpdateTransformation();
}

MoveList Chessman::GetLegalMoves( Chessman* chessboard[8][8] )
{
	MoveList list;
	Game* game = Game::GetGame();

	int offsets[] = {
		1, 1,
		1, -1,
		-1, 1,
		-1, -1,
		2, 2,
		2, -2,
		-2, -2,
		-2, 2,
	};

	for (int i = 0; i < 8; i++)
	{
		int x = offsets[i*2] + mPosX;
		int y = offsets[i*2+1] + mPosY;

		if (x < 1 || x > 8 || y < 1 || y > 8)
		{
			continue;
		}

		if (!mIsKing)
		{
			if (mOwner == PLAYER_ONE && y <= mPosY)
			{
				continue;
			}
			else if (mOwner == PLAYER_TWO && y >= mPosY)
			{
				continue;
			}
		}

		int dist = abs(x - mPosX) + abs(y - mPosY);

		if (dist == 2)
		{
			if (game->GetChessmanAtPosition(x, y))
			{
				continue;
			}
		}
		else {
			Chessman* enemy = game->GetChessmanAtPosition( (x+mPosX)/2, (y+mPosY)/2 );
			if (!enemy || enemy->GetOwner() == mOwner)
			{
				continue;
			}
		}

		list.push_back(Vector2(x, y));
	}

	return list;
}
